#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)

#include <stdio.h>

// F5 - 启动调试
// F9 - 设置/取消断点
// F10 - 逐过程
// F11 - 逐语句

//void test2()
//{
//	printf("Hello World");
//}
//
//void test1()
//{
//	test2();
//}
//
//void test()
//{
//	test1();
//}
//
//// 调试 - 调用堆栈
//int main()
//{
//	test();
//
//	return 0;
//}

//int main()
//{
//	int arr[10] = { 0 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	for (int i = 0; i < sz; i++)
//	{
//		arr[i] = i + 1;
//	}
//
//	for (int i = 0; i < sz; i++)
//	{
//		printf("%d\n", arr[i]);	//F9，右键选择条件断点
//	}
//}

// 《C陷阱与缺陷》
// i和arr是局部变量
// 局部变量是放在栈区上的
// 
// 栈区的使用习惯是：
// 先使用高地址，再使用低地址空间
// 
// 数组随着下标的增长地址
// 是由低到高变化的
// 
// 当i的地址刚好和arr[i]重合时，就会进入死循环
// 
//int main()
//{
//	int i = 0;
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	for ( i = 0; i <= 12; i++)
//	{
//		arr[i] = 0;
//		printf("test\n");
//	}
//	
//	return 0;
//}

// 模拟实现strcpy字符串拷贝
//void my_strcpy(char* dest, char* src)
//{
//	while (*src != '\0')
//	{
//		*dest = *src;
//		dest++;
//		src++;
//	}
//	*dest = *src;
//}

//#include <assert.h>
//void my_strcpy(char* dest, const char* src)
//{
//	assert(dest != NULL);	// 断言
//	assert(src != NULL);	// 断言
//
//	//while (*src++ = *dest);	const修饰不可修改
//	while (*dest++ = *src++);
//}
//
//int main()
//{
//	char arr1[20] = "";
//	char arr2[] = "hello";
//
//	my_strcpy(arr1, arr2);
//	printf("%s\n", arr1);
//
//	return 0;
//}

//int main()
//{
//	// 1.
//	//int num = 10;
//	//int* p = &num;
//	//*p = 20;
//	//printf("%d\n", num);
//
//	// 2.
//	// const修饰变量，这个变量被称为常变量，不能被修改，但是本质上还是变量
//	//const int num = 10;
//	// const修饰指针变量
//	// const 如果放在*的左边，修饰的是*p，表示指针指向的内容，是不能通过指针来改变
//	//const int* p = &num;
//	//*p = 20;
//	// 指针变量本身可以修改
//	//int n = 20;
//	//p = &n;
//
//	int num = 10;
//	// 3.
//	// const修饰指针变量
//	// const 如果放在*的右边，修饰的是指针变量p,p不能被改变
//	// 但是指向的内容可以改变
//	//int* const p = &num;
//	//*p = 20;
//
//	int const* p = num;
//	num = 20;
//
//	printf("%d\n", num);
//}
// 1.参数类型 const
// 2.assert
// 3.函数体
// 4.返回类型
#include <assert.h>
//char* my_strcpy(char* dest, const char* src)
//{
//	assert(dest != NULL);
//	assert(src != NULL);
//	char* ret = dest;
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}

// size_t - unsigned int
//size_t my_strlen(const char* str)
//{
//	//assert(str != NULL);
//	assert(str);
//	int count = 0;
//	while (*str++ != '\0')
//	{
//		count++;
//	}
//
//	return count;
//}
//
//int main()
//{
//	char* str = "Hello World!";
//	printf("%u\n", my_strlen(str));
//
//	return 0;
//}
// 计算参数n的二进制补码中有几个1
// 负数时计算补码
// 1.
//int NumberOf1(unsigned int n)
//{
//	int count = 0;
//	while (n)
//	{
//		if (n % 2 == 1)
//		{
//			count++;
//		}
//		n /= 2;
//	}
//	return count;
//}
//2.
//int NumberOf1(int n)
//{
//	int count = 0;
//	for (int i = 0; i < 32; i++)
//	{
//		if ((n>>i) & 1 == 1)
//		{
//			count++;
//		}
//	}
//	
//	return count;
//}
//3.
//int NumberOf1(int n)
//{
//	int count = 0;
//	while (n)
//	{
//		n = n & (n - 1);
//		count++;
//	}
//	return count;
//}
//写一个代码判断一个数字是不是2的n次方
//2的n次方的数字，其中只有一个1

//int main()
//{
//	int n = -1;
//	int ret = NumberOf1(n);
//
//	printf("%d\n", ret);
//	return 0;
//}

//int main()
//{
//	int a = 0;
//	int b = 0;
//	scanf("%d %d", &a, &b);
//	for (int i = 0;; i++)
//	{
//		if (a*i%b == 0)
//		{
//			printf("%d\n", a * i);
//			break;
//		}
//	}
//	return 0;
//}

//void reverse(char* left, char* right)
//{
//	while (left < right)
//	{
//		char tmp = 0;
//		tmp = *left;
//		*left = *right;
//		*right = tmp;
//
//		left++;
//		right--;
//	}
//}
//
//int main()
//{
//	char arr[100] = { 0 };
//	gets(arr);
//	//三步翻转法
//	//1.字符串整体翻转
//	int len = strlen(arr);
//	reverse(arr, arr+len-1);
//	//2.每个单词逆序
//	char* start = arr;
//	while (*start)
//	{
//		char* end = start;
//		while (*end != ' ' && *end != '\0')
//		{
//			end++;
//		}
//		reverse(start, end - 1);
//		if (*end == ' ')
//		{
//			start = end + 1;
//		}
//		else
//		{
//			start = end;
//		}
//	}
//	printf("%s\n", arr);
//
//	return 0;
//}